	package com.lethelh.mgallery.utils;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import com.lethelh.mgallery.entity.Painting;

/**
 * 数据源类，用于将XML文件解析为Java对象
 * 
 * @author LetheLH
 *
 */
public class XmlDataSource {
	// 通过static静态关键字保证数据的全局唯一
	private static List<Painting> data = new ArrayList<Painting>();
	private static String dataFile;
	static {
		// 得到painting.xml文件完整的物理路径
		dataFile = XmlDataSource.class.getResource("/painting.xml").getPath();
		reload();
	}

	private static void reload() {
		// 将bsae64编码转换为标准字符串
		URLDecoder decoder = new URLDecoder();
		try {
			dataFile = decoder.decode(dataFile, "UTF-8");
			System.out.println(dataFile);
			// 利用Dom4j对XML进行解析
			SAXReader reader = new SAXReader();
			// 1.获取Document文档对象
			Document document = reader.read(dataFile);
			// 2.Xpath得到XML节点集合
			List<Node> nodes = document.selectNodes("/root/painting");
			data.clear();
			for (Node node : nodes) {
				Element element = (Element) node;
				String id = element.attributeValue("id");
				String pname = element.elementText("pname");
				Painting painting = new Painting();
				painting.setId(Integer.parseInt(id));
				painting.setPname(pname);
				painting.setCategory(Integer.parseInt(element.elementText("category")));
				painting.setPrice(Integer.parseInt(element.elementText("price")));
				painting.setPreview(element.elementText("preview"));
				painting.setDescription(element.elementText("description"));

				data.add(painting);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 获取所有油画Painting对象
	 * 
	 * @return Painting List
	 */
	public static List<Painting> getRawData() {
		return data;
	}

	public static void append(Painting painting) {
		// 1.读取XML文档，得到Document对象
		SAXReader reader = new SAXReader();
		Writer writer = null;
		try {
			Document document = reader.read(dataFile);
			// 2.创建新的painting节点
			Element root = document.getRootElement();
			Element p = root.addElement("painting");
			// 3.创建painting节点的各个子节点
			p.addAttribute("id", String.valueOf(data.size() + 1));
			p.addElement("pname").setText(painting.getPname());
			p.addElement("category").setText(painting.getCategory().toString());
			p.addElement("price").setText(painting.getPrice().toString());
			p.addElement("preview").setText(painting.getPreview());
			p.addElement("description").setText(painting.getDescription());
			// 4.写入XML，完成追加操作
			writer = new OutputStreamWriter(new FileOutputStream(dataFile), "UTF-8");
			document.write(writer);
			System.out.println(dataFile);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (writer != null) {
				try {
					writer.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			reload();//内存与文件数据一致
		}

	}

	/**
	 * 更新对应id的XML油画数据
	 * @param painting
	 */
	public static void update(Painting painting) {
		SAXReader reader = new SAXReader();
		Writer writer = null;
		try {
			Document document = reader.read(dataFile);
			//节点路径[@属性名=属性值]
			// /root/painting[@id=x]
			List<Node> nodes = document.selectNodes("/root/painting[@id="+painting.getId()+"]");
			if(nodes.size() == 0) {
				throw new RuntimeException("id="+painting.getId()+"编号油画不存在");
			}
			Element p = (Element) nodes.get(0);
			p.selectSingleNode("pname").setText(painting.getPname());
			p.selectSingleNode("category").setText(painting.getCategory().toString());
			p.selectSingleNode("price").setText(painting.getPrice().toString());
			p.selectSingleNode("preview").setText(painting.getPreview());
			p.selectSingleNode("description").setText(painting.getDescription());
			writer = new OutputStreamWriter(new FileOutputStream(dataFile),"UTF-8");
			document.write(writer);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(writer != null) {
				try {
					writer.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			reload();
		}
	}
	
	public static void  delete(Integer id) {
		//		1） 用SAXReader来读取xml文件，SAXReader对象的read()方法传入dataFile来读取Document对象。
		SAXReader reader = new SAXReader();
		Writer writer = null;
		try {
			Document document = reader.read(dataFile);
			//			2） 对数据进行筛选，选出指定id的数据（可以参考XMLDataSource中update方法中获取指定id方法的代码），并使用List保存查询结果

			List<Node> nodes =  document.selectNodes("/root/painting[@id="+id+"]");
			//3） 如果指定id不存在，则抛出RuntimeException异常
			//4） 如果存在则删除，具体参照如下内容完成
			//	a) 得到Element对象 例如命名为Element p，可以通过p.getParent（）得到上级节点，同时上级节点使用remove方法删除p这个Element对象。
			//	b) 知识点：remove方法是用来删除指定的子节点
			if(nodes.size() == 0) {
				throw new RuntimeException("id="+id+"编号油画不存在");
			}
			Element p = (Element) nodes.get(0);
			p.getParent().remove(p);
			//5） 实例化Writer对象writer ，利用document.write(writer)回写数据
			writer = new OutputStreamWriter(new FileOutputStream(dataFile), "UTF-8");
			document.write(writer);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//6） 关闭writer
			if(writer != null) {
				try {
					writer.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			//7） reload（）方法对数据进行重新加载
			reload();
		}
	}
	public static void main(String[] args) {
//		List<Painting> ps = XmlDataSource.getRawData();
		Painting p = new Painting();
		p.setPname("测试油画");
		p.setCategory(1);
		p.setPrice(4000);
		p.setPreview("/upload/10.jpg");
		p.setDescription("测试油画描述");
		XmlDataSource.append(p);
	}
}
